#include "HiranipraShared.h"

#include "Platform/IO/MemoryBuffer.h"
#include "Platform/IO/IFileSystem.h"

#ifndef _SHARED_PLATFORM_IO_IOQUEUE_H_
#define _SHARED_PLATFORM_IO_IOQUEUE_H_

namespace Hiranipra {
	namespace Platform {
		namespace IO {

			class IOEvent;

			class IOQueue : implements RefInstance
			{
			public:
				IOQueue( IFileSystem* fileSystem );
				virtual ~IOQueue();

				uint32 BeginRead( IFileStream* sourceStream, MemoryBuffer* buffer );
				uint32 BeginWrite( IFileStream* targetStream, MemoryBuffer* buffer );

				bool IsComplete( uint32 requestId ) const;

				bool Cancel( uint32 requestId );

			public:
				EventSource<IOEvent>		EventSource;

			public:
				FORCE_INLINE IFileSystem*	GetFileSystem(){ return _fs; }

			private:
				class IORunner; friend class IORunner;
				class IORequest;
				IORunner*			_ioRunner;
				Thread*				_ioThread;

				IFileSystem*		_fs;

				AtomicCount			_requestIds;
				BlockingQueue<IORequest*, Mutex>*	_requests;
			};

			class IOEvent : public Event
			{
			public:
				enum IOEventName
				{
					ReadCompleted,
					WriteCompleted,
				};
			public:
				IOEvent( IOEventName name, uint32 requestId, bool successful, IFileStream* stream = NULL, MemoryBuffer* buffer = NULL ) :
					Event( name ),
					RequestID( requestId ),
					Successful( successful ),
					Stream( stream ),
					Buffer( buffer )
				{
					if( stream != NULL )
						stream->Retain();
					if( buffer != NULL )
						buffer->Retain();
				}
				virtual ~IOEvent()
				{
					RELEASE( this->Stream );
					RELEASE( this->Buffer );
				}
			public:
				uint32			RequestID;
				bool			Successful;
				IFileStream*	Stream;
				MemoryBuffer*	Buffer;
			};

		}
	}
}

#endif // _SHARED_PLATFORM_IO_IOQUEUE_H_
